package research;

import java.io.File;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopScoreDocCollector;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.LockObtainFailedException;
import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.store.SimpleFSDirectory;
import org.apache.lucene.util.Version;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;

public class LuceneIndexManager {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		try{
			SimpleFSDirectory index = new SimpleFSDirectory(new File("D:/product_data/sku_name_mapping_index"));
			StandardAnalyzer analyzer = new StandardAnalyzer(Version.LUCENE_36);			

			//buildLuceneIndex(index,analyzer);

			IndexReader reader = IndexReader.open(index);
			IndexSearcher searcher = new IndexSearcher(reader);

			Query q = new QueryParser(Version.LUCENE_36, "sku", analyzer).parse("430420");
			ScoreDoc[] hits = searchLuceneIndex(q, searcher);

			int docId = hits[0].doc;
			Document d = searcher.doc(docId);
			System.out.println(d.get("name"));

		}catch(Exception e){
			e.printStackTrace();
		}
	}

	public static void buildLuceneIndex(SimpleFSDirectory index, StandardAnalyzer analyzer){
		try{
			IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_36,analyzer);

			IndexWriter w = new IndexWriter(index, config);			

			File fileDir=new File("D:/product_data/products");
			File[] files=fileDir.listFiles();
			int fileIndex = 1;
			for(File file:files){
				processXml(file,w);
				System.out.println(fileIndex);
				fileIndex++;
			}
			w.close();
		}catch(Exception e){
			e.printStackTrace();
		}		
	}

	private static void addDoc(IndexWriter w, String sku, String name) throws IOException {
		Document doc = new Document();
		doc.add(new Field("sku", sku, Field.Store.YES, Field.Index.ANALYZED));
		doc.add(new Field("name", name, Field.Store.YES, Field.Index.ANALYZED));
		w.addDocument(doc);
	}

	public static ScoreDoc[] searchLuceneIndex(Query q, IndexSearcher searcher) throws IOException{
		int hitsPerPage = 1;
		TopScoreDocCollector collector = TopScoreDocCollector.create(hitsPerPage, true);
		searcher.search(q, collector);
		ScoreDoc[] hits = collector.topDocs().scoreDocs;
		return hits;
	}

	public static void processXml(File xmlFile, IndexWriter w){
		try {
			DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
			org.w3c.dom.Document doc = dBuilder.parse(xmlFile);
			doc.getDocumentElement().normalize();

			//System.out.println("Root element :" + doc.getDocumentElement().getNodeName());
			NodeList nList = doc.getElementsByTagName("product");
			//System.out.println("-----------------------");

			for (int temp = 0; temp < nList.getLength(); temp++) {

				Node nNode = nList.item(temp);
				if (nNode.getNodeType() == Node.ELEMENT_NODE) {
					Element eElement = (Element) nNode;
					addDoc(w,getTagValue("sku",eElement),getTagValue("name",eElement));
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	private static String getTagValue(String sTag, Element eElement) {
		NodeList nlList = eElement.getElementsByTagName(sTag).item(0).getChildNodes();
		Node nValue = (Node) nlList.item(0);
		return nValue.getNodeValue();
	}

}
